package com.yq.cp.utils;


import javax.xml.crypto.Data;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 *
 * 时间
 *
 */
public class DateTimeUtil {
    public static final String SIMPLE_DATE = "yyyy-MM-dd";

    public static final String SIMPLE_TIME = "HH:mm:ss";

    public static final String SIMPLE_DATE_TIME = "yyyy-MM-dd HH:mm:ss";
    /**
     * 获得某个月最大天数
     * @param year 年份
     * @param month 月份 (1-12)
     * @return 某个月最大天数
     */
    public static int getMaxDayByYearMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, 1);
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month - 1);
        return calendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 获得某个月最大天数
     * @return 某个月最大天数
     */
    public static int getMaxDayByYearMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DATE, 1);
        calendar.set(Calendar.YEAR, getYear());
        calendar.set(Calendar.MONTH, getMonth() - 1);
        return calendar.getActualMaximum(Calendar.DATE);
    }

    /**
     * 获取当前时间
     */
    public static String getCurrentDay() {
        Date now = DateTimeUtil.dqsj();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(now);
    }
    /**
     * 获取当前时间
     */
    public static Date dqsj() {
        // 设置北京时区
        ZoneId zoneId = ZoneId.of("Asia/Shanghai");

        // 获取当前北京时间
        ZonedDateTime beijingTime = ZonedDateTime.now(zoneId);

        // 输出北京时间
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedTime = beijingTime.format(formatter);
//        System.out.println("当前北京时间是: " + formattedTime);

        return DateTimeUtil.toSimpleDateTime(formattedTime);
    }
    /**
     * 将时间转换成yyyy-MM-dd HH:mm:ss格式
     */
    public static String getStrDateTime(Date date) {
        if (date==null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(date);
    }

    /**
     * 将时间转换成yyyyMMddHHmmss格式
     */
    public static String getStrDateTime1(Date date) {
        if (date==null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(date);
    }

    /**
     * 将时间转换成yyyy-MM-dd HH:mm格式
     */
    public static String getStrDateTime2(Date date) {
        if (date==null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(date);
    }

    /**
     * 将时间转换成yyyy-MM-dd格式
     */
    public static String getStrDateTime3(Date date) {
        if (date==null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(date);
    }
    /**
     * 将时间转换成yyyy-MM-dd HH:mm:ss:SSS格式
     */
    public static String getStrDateTime4(Date date) {
        if (date==null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(date);
    }
    /**
     * 将时间转换成HH:mm格式
     */
    public static String getStrDateTime5(Date date) {
        if (date==null) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(date);
    }
    /**
     * 得到几天前的时间
     *
     * @param d
     * @param day
     * @return
     */
    public static Date getDateBefore(Date d, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
        return now.getTime();
    }

    /**
     * 得到几天后的时间
     *
     * @param d
     * @param day
     * @return
     */
    public static Date getDateAfter(Date d, int day) {
        Calendar now = Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + day);
        return now.getTime();
    }
    /**
     * 比较两个日期的先后
     * 第一个时间大于第二个时间，返回true,否则返回false
     * */
    public static boolean compare(String beginTime,String endTime) {
        if(Long.valueOf(beginTime.replaceAll("-",""))>Long.valueOf(endTime.replaceAll("-", ""))){
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据时间获取文件路径
     * */
    public static String file() {
        Calendar cal = Calendar.getInstance();
        int day = cal.get(Calendar.DATE);
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);
        return year+"\\"+month+"\\"+day+"\\";
    }

    /**
     * 获取时间差
     * */
    public static long timeDifference(Date begin,Date over) {
        long diff = over.getTime() - begin.getTime();

        return diff;
    }
    public static Date getDateTime(long timestamp) {
        return new Date(timestamp);
    }

    public static String format(Date date, String patten) {
        SimpleDateFormat sdf = new SimpleDateFormat(patten);

        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        return sdf.format(date);
    }

    /**
     *
     * @see #SIMPLE_DATE
     */
    public static String simpleDate(Date date) {
        return format(date, SIMPLE_DATE);
    }

    /**
     *
     * @see #SIMPLE_TIME
     */
    public static String simpleTime(Date date) {
        return format(date, SIMPLE_TIME);
    }

    /**
     *
     * @see #SIMPLE_DATE_TIME
     */
    public static String simpleDateTime(Date date) {
        return format(date, SIMPLE_DATE_TIME);
    }

    public static Date toDate(String dateString, String patten) {
        SimpleDateFormat sdf = new SimpleDateFormat(patten);
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        try {
            return sdf.parse(dateString);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * @see #SIMPLE_DATE
     */
    public static Date toSimpleDate(String dateString) {
        return toDate(dateString, SIMPLE_DATE);
    }

    /**
     *
     * @see #SIMPLE_TIME
     */
    public static Date toSimpleTime(String dateString) {
        return toDate(dateString, SIMPLE_TIME);
    }

    /**
     *
     * @see #SIMPLE_DATE_TIME
     */
    public static Date toSimpleDateTime(String dateString) {
        return toDate(dateString, SIMPLE_DATE_TIME);
    }

    public static int getYear() {
        String year=String.format("%tY", DateTimeUtil.dqsj());
        return Integer.parseInt(year);
    }
    public static int getMonth() {
        String mon=String .format("%tm", DateTimeUtil.dqsj());
        return Integer.parseInt(mon);
    }
    public static int getDay() {
        String day=String .format("%td", DateTimeUtil.dqsj());
        return Integer.parseInt(day);
    }

    public static int getYear(Date date) {

        if (date==null){
            date=DateTimeUtil.dqsj();
        }
        String year=String.format("%tY", date);
        return Integer.parseInt(year);
    }
    public static int getMonth(Date date) {
        if (date==null){
            date=DateTimeUtil.dqsj();
        }
        String mon=String .format("%tm", date);
        return Integer.parseInt(mon);
    }
    public static int getDay(Date date) {
        if (date==null){
            date=DateTimeUtil.dqsj();
        }
        String day=String .format("%td", date);
        return Integer.parseInt(day);
    }
    /** 当前时间后的几分钟时间 */
    public static Date laterDateTime(int i) {
        Long time = System.currentTimeMillis();
        time +=i*60*1000;
        Date date = new Date(time);
        return date;
    }
    /** 当前时间的前几分钟时间 */
    public static Date frontDateTime(int i) {
        Long time = System.currentTimeMillis();
        time -=i*60*1000;
        Date date = new Date(time);
        return date;
    }

    /**
     * 根据年 月 获取对应的月份 天数
     */
    public static int getDaysByYearMonth(int year, int month) {

        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }

    /**
     * 获取当前时间所在周的周一和周日的日期时间 yyyy-MM-dd HH:mm:ss
     * @return
     */
    public static Map<String,String> getWeekDate1() {
        Map<String,String> map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));

        Calendar cal = Calendar.getInstance();
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if(dayWeek==1){
            dayWeek = 8;
        }

        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = getTodayStartTime(mondayDate);
//        String weekBegin = sdf.format(mondayDate);

        cal.add(Calendar.DATE, 4 +cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        String weekEnd = getEndOfDay(sundayDate);
//        String weekEnd = sdf.format(sundayDate);

        map.put("mondayDate", weekBegin);
        map.put("sundayDate", weekEnd);
        return map;
    }


    /**
     * 获取当前时间所在周的周一和周日的日期时间
     * @return
     */
    public static Map<String,String> getWeekDate() {
        Map<String,String> map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));

        Calendar cal = Calendar.getInstance();
        // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if(dayWeek==1){
            dayWeek = 8;
        }

        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
        Date mondayDate = cal.getTime();
        String weekBegin = sdf.format(mondayDate);

        cal.add(Calendar.DATE, 4 +cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        String weekEnd = sdf.format(sundayDate);

        map.put("mondayDate", weekBegin);
        map.put("sundayDate", weekEnd);
        return map;
    }




    /**
     * 获取指定日期所在周的周一
     *
     * @param date 日期
     */
    public static Date getFirstDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            c.add(Calendar.DAY_OF_MONTH, -1);
        }
        c.add(Calendar.DATE, c.getFirstDayOfWeek() - c.get(Calendar.DAY_OF_WEEK) + 1);
        return c.getTime();
    }
    /**
     * 获取指定日期所在周的周日
     *
     * @param date 日期
     */
    public static Date getLastDayOfWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // 如果是周日直接返回
        if (c.get(Calendar.DAY_OF_WEEK) == 1) {
            return date;
        }
        //System.out.println(c.get(Calendar.DAY_OF_WEEK));
        c.add(Calendar.DATE, 7 - c.get(Calendar.DAY_OF_WEEK) + 1);
        return c.getTime();
    }


    /**
     * 获取当前月第一天起始时间 yyyy-MM-dd HH:mm:ss
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth1(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最小天数
        int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        // 设置日历中月份的最小天数
        calendar.set(Calendar.DAY_OF_MONTH, firstDay);
        Date time = calendar.getTime();
        String sj = getTodayStartTime(time);
        return sj;
    }

    /**
     * 获取当前月第一天
     * @param month
     * @return
     */
    public static String getFirstDayOfMonth(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最小天数
        int firstDay = calendar.getActualMinimum(Calendar.DAY_OF_MONTH);
        // 设置日历中月份的最小天数
        calendar.set(Calendar.DAY_OF_MONTH, firstDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String sj = sdf.format(calendar.getTime());
        return sj;
    }


    /**
     * 获取当前月最后一天 yyyy-MM-dd HH:mm:ss
     * @param month
     * @return
     */
    public static String getLastDayOfMonth1(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay=0;
        //2月的平年瑞年天数
        if(month==2) {
            lastDay = calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);
        }else {
            lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        Date time = calendar.getTime();
        String sj = getEndOfDay(time);
        return sj;
    }

    /**
     * 获取当前月最后一天
     * @param month
     * @return
     */
    public static String getLastDayOfMonth(int month) {
        Calendar calendar = Calendar.getInstance();
        // 设置月份
        calendar.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay=0;
        //2月的平年瑞年天数
        if(month==2) {
            lastDay = calendar.getLeastMaximum(Calendar.DAY_OF_MONTH);
        }else {
            lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        }
        // 设置日历中月份的最大天数
        calendar.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String sj = sdf.format(calendar.getTime());
        return sj;
    }



    /** 查询当前日期 */
    public static String today() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        String today = sdf.format(DateTimeUtil.dqsj());//当天日期
        return today;
    }

    /**
     * 获取某天起始时间
     * @return
     */
    public static String getTodayStartTime(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }

    /**
     * 获取某天结束时间
     * @return
     */
    public static String getEndOfDay(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }

    /**
     * 获取上个月的起始时间和结束时间
     * @return
     */
    public static Map<String, String> getLastOneMonthDay() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        Map<String, String> map = new HashMap<>();
        // 上月起始
        Calendar lastMonthFirstDateCal = Calendar.getInstance();
        lastMonthFirstDateCal.add(Calendar.MONTH, -1);
        lastMonthFirstDateCal.set(Calendar.DAY_OF_MONTH, 1);
        String lastMonthFirstTime = getTodayStartTime(lastMonthFirstDateCal.getTime());

        // 上月末尾
        Calendar lastMonthEndDateCal = Calendar.getInstance();
        lastMonthEndDateCal.add(Calendar.MONTH, -1);
        lastMonthEndDateCal.set(
                Calendar.DAY_OF_MONTH, lastMonthEndDateCal.getActualMaximum(Calendar.DAY_OF_MONTH));
        String lastMonthEndTime = getEndOfDay(lastMonthEndDateCal.getTime());
        map.put("beginDate", lastMonthFirstTime);
        map.put("endDate", lastMonthEndTime);
        return map;
    }


    /**
     * 获取指定日期当日每个小时的起始时间和结束时间
     * @param
     * @return java.util.Date
     */
    public static Map<String, List<String>> beforeOneHourToNowDate(Date data) {
        Calendar calendar = Calendar.getInstance();
        Calendar calendar1 = Calendar.getInstance();


        String startTime = DateTimeUtil.getTodayStartTime(data);
        String lastTime = DateTimeUtil.getEndOfDay(data);
        Date sTime = toSimpleDateTime(startTime);
        Date lTime = toSimpleDateTime(lastTime);
        List<String> startTimes = new ArrayList<>();
//        startTimes.add(startTime);
        List<String> lastTimes = new ArrayList<>();
        for (int i = 1; i <= 24; i++) {
            //起始时间
            calendar.setTime(sTime);
            calendar.add(Calendar.HOUR_OF_DAY,i-1);
            startTimes.add(simpleDateTime(calendar.getTime()));
            //结束时间
            calendar1.setTime(lTime);
            calendar1.add(Calendar.HOUR_OF_DAY,-(i-1));
            lastTimes.add(simpleDateTime(calendar1.getTime()));
        }
        Map<String, List<String>> map = new HashMap<>();
        map.put("startTimes",startTimes);
        map.put("lastTimes",lastTimes);
        return map;
    }

    public static List<String> getTwoDaysDayDes(String startDate, String endDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        List<String> dateList = new ArrayList<>();
        try {
            Date dateOne = sdf.parse(startDate);
            Date dateTwo = sdf.parse(endDate);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(dateOne);
            Date date = toSimpleDate(startDate);
            String s = simpleDate(date);
            dateList.add(s);
            while (dateTwo.after(calendar.getTime())) {
                calendar.add(Calendar.DAY_OF_MONTH, 1);
                dateList.add(sdf.format(calendar.getTime()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return dateList;
    }


    public static Integer getHour(){
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        return hour;
    }

    public static Integer getMinute(Date date){
        // 步骤2：创建一个Calendar对象
        Calendar calendar = Calendar.getInstance();

        // 步骤3：将Date对象设置到Calendar对象中
        calendar.setTime(date);

        // 步骤4：从Calendar对象中获取当前分钟
        int currentMinute = calendar.get(Calendar.MINUTE);
        return currentMinute;
    }


    /**
     * 获取两个日期之间的所有月份 (年月)(格式:2023-04-00)
     *
     * @param startTime
     * @param endTime
     * @return：list
     */
    public static List<String> getMonthBetweenDate(String startTime, String endTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        // 声明保存日期集合
        List<String> list = new ArrayList<>();
        try {
            // 转化成日期类型
            Date startDate = sdf.parse(startTime);
            Date endDate = sdf.parse(endTime);

            //用Calendar 进行日期比较判断
            Calendar calendar = Calendar.getInstance();
            while (startDate.getTime() <= endDate.getTime()) {

                // 把日期添加到集合
                //把日期拼成2023-04-00格式
                String s = sdf.format(startDate);
                list.add(s);

                // 设置日期
                calendar.setTime(startDate);

                //把月数增加 1
                calendar.add(Calendar.MONTH, 1);

                // 获取增加后的日期
                startDate = calendar.getTime();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
    /**
     * 获取日期是周几
     */
    public static Integer zhouji(Date date){
        final String dayNames[] = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五",
                "星期六" };
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK)-1;
        System.out.println(dayNames[dayOfWeek]);
        return  dayOfWeek;
    }

    /**
     * 比较两个日期 相差多少天
     */
    public static long getDaysBetweenDates(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);
        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        long diff = cal2.getTimeInMillis() - cal1.getTimeInMillis();
        return diff / (24 * 60 * 60 * 1000);
    }
}
